#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/compression/octree_pointcloud_compression.h>

#include <stdio.h>
#include <sstream>

#include "pointCloudDist.h"
#include "pointCloud.h"


namespace eqPc
{

	pcl::octree::compression_Profiles_e compressionProfile = pcl::octree::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;	

	void PointCloudDist::getInstanceData(co::DataOStream& os){
		int i = _pointCloud->_cloud->points.size();
		os<<i;
		float x,y,z;
		uint8_t r,g,b;
		for(size_t i = 0;i<_pointCloud->_cloud->points.size();i++){
			x = _pointCloud->_cloud->points[i].x;
			y = _pointCloud->_cloud->points[i].y;
			z = _pointCloud->_cloud->points[i].z;
			r = _pointCloud->_cloud->points[i].r;
			g = _pointCloud->_cloud->points[i].g;
			b = _pointCloud->_cloud->points[i].b;
			os<<x<<y<<z<<r<<g<<b;
		}

	}

	void PointCloudDist::applyInstanceData(co::DataIStream& is){
		EQASSERT( !_pointCloud );
		_pointCloud = new pc::PointCloud();
		int n;
		is>>n;

		_pointCloud->_cloud->points.resize(n);
		float x,y,z;
		uint8_t r,g,b;
		for(int i = 0; i<n;i++)
		{
			is>>x>>y>>z>>r>>g>>b;

			_pointCloud->_cloud->points[i].x=x;
			_pointCloud->_cloud->points[i].y=y;
			_pointCloud->_cloud->points[i].z=z;
			_pointCloud->_cloud->points[i].r=r;
			_pointCloud->_cloud->points[i].g=g;
			_pointCloud->_cloud->points[i].b=b;

		}
		

	
	}
	void PointCloudDist::registerPointCloud(co::LocalNodePtr node)
	{
	    EQASSERT( !isAttached() );
	    EQCHECK( node->registerObject( this ));
	}

	void PointCloudDist::deregisterPointCloud()
	{
		EQASSERT( isAttached() );
		EQASSERT( isMaster( ));

		getLocalNode()->deregisterObject( this );	
	
	}
	pc::PointCloud* PointCloudDist::mapPointCloud( co::LocalNodePtr node, const eq::uint128_t& modelID ){
		EQASSERT( !_pointCloud );

		if( !node->mapObject( this, modelID ))
		{
			EQWARN << "Mapping of model failed" << std::endl;
			return 0;
		}

		return const_cast< pc::PointCloud* >( _pointCloud );
	
	}
	void PointCloudDist::unmapPointCloud()
	{
		EQASSERT( isAttached() );
		EQASSERT( !isMaster( ));

		getLocalNode()->unmapObject( this );

	}

	PointCloudDist::~PointCloudDist()
	{
		delete _pointCloud;
		_pointCloud=0;
	}
}